package cn.fz.utils;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.crypto.asymmetric.SM2;

import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

public class SM2CryptoUtils {
    /**
     * SM2私钥签名（带URL编码）
     * @param data 待签名数据（原文）
     * @param priKeyHex 十六进制格式的私钥
     * @return URL编码后的Base64签名值
     */
    public static String signWithUrlEncode(String data, String priKeyHex) {
        try {
            // 1. 创建SM2实例（仅使用私钥）
            SM2 sm2 = new SM2(priKeyHex, null);

            // 2. 生成签名（Base64编码）
            byte[] signature = sm2.sign(data.getBytes(CharsetUtil.CHARSET_UTF_8));
            String base64Sign = Base64.encode(signature);
            System.out.println(base64Sign);
            // 3. URL编码处理（防止特殊字符传输问题）
            return URLEncoder.encode(base64Sign, StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new RuntimeException("SM2签名失败", e);
        }
    }

    /**
     * SM2公钥验签（自动处理URL解码）
     * @param data 原始数据（原文）
     * @param encodedSign URL编码后的签名
     * @param pubKeyHex 十六进制格式的公钥
     * @return 验签结果 true/false
     */
    public static boolean verifyWithUrlDecode(String data, String encodedSign, String pubKeyHex) {
        try {
            // 1. URL解码获取原始签名
            String base64Sign = URLDecoder.decode(encodedSign, StandardCharsets.UTF_8);

            // 2. 创建SM2实例（仅使用公钥）
            SM2 sm2 = new SM2(null, pubKeyHex);

            // 3. 执行验签
            return sm2.verify(
                    data.getBytes(CharsetUtil.CHARSET_UTF_8),
                    Base64.decode(base64Sign)
            );
        } catch (Exception e) {
            throw new RuntimeException("SM2验签失败", e);
        }
    }

    /**
     * 生成SM2密钥对（兼容在线工具）
     * @return String[0]=私钥(hex), String[1]=公钥(hex)
     */
    public static String[] generateKeyPair() {
        SM2 sm2 = new SM2();
        return new String[] {
                sm2.getPrivateKeyBase64(), // 实际应使用getPrivateKeyHex()
                sm2.getPublicKeyBase64().replaceAll("\\s", "") // 公钥去空格
        };
    }

}
